<?php

namespace Resmodel\Factory;

use Core\Db\Feature\InjectMetaFieldFeature;
use Core\Db\Feature\LightMetaFeature;
use Resmodel\Address;
use Resmodel\AddressTable;

use Resmodel\Category;
use Resmodel\CategoryTable;
use Resmodel\DayDish;
use Resmodel\DayDishTable;
use Resmodel\Dish;
use Resmodel\DishArticle;
use Resmodel\DishArticleTable;
use Resmodel\DishCategory;
use Resmodel\DishCategoryTable;
use Resmodel\DishImage;
use Resmodel\DishImageTable;
use Resmodel\DishLang;
use Resmodel\DishLangTable;
use Resmodel\DishPrice;
use Resmodel\DishPriceTable;
use Resmodel\DishTable;
use Resmodel\DishTag;
use Resmodel\DishTagTable;


use Resmodel\MlCategory;
use Resmodel\MlCategoryLang;
use Resmodel\MlCategoryLangTable;
use Resmodel\MlCategoryTable;
use Resmodel\Province;
use Resmodel\ProvinceTable;
use Resmodel\ResAbstractTable;

use Resmodel\Tag;
use Resmodel\ArticleTag;
use Resmodel\ArticleCategory;
use Resmodel\Article;

use Resmodel\ArticleCategoryTable;
use Resmodel\ArticleTable;
use Resmodel\BlockClass;
use Resmodel\BlockClassTable;
use Resmodel\BlockInstance;
use Resmodel\BlockInstanceTable;
use Resmodel\CountryTable;
use Resmodel\Menu;
use Resmodel\MenuItem;
use Resmodel\MenuItemTable;
use Resmodel\MenuTable;
use Resmodel\Page;
use Resmodel\PageBlock;
use Resmodel\PageBlockTable;
use Resmodel\PageTable;
use Resmodel\Privilege;
use Resmodel\PrivilegeTable;
use Resmodel\PrivilegeType;
use Resmodel\PrivilegeTypeTable;
use Resmodel\Role;
use Resmodel\RolePrivilegeTable;
use Resmodel\RoleTable;
use Resmodel\Route;
use Resmodel\RouteTable;
use Resmodel\Template;
use Resmodel\TemplateBlock;
use Resmodel\TemplateBlockTable;
use Resmodel\TemplateTable;
use Resmodel\Unit;
use Resmodel\UnitLang;
use Resmodel\UnitLangTable;
use Resmodel\UnitTable;
use Resmodel\User;
use Resmodel\UserBalance;
use Resmodel\UserBalanceTable;
use Resmodel\UserRole;
use Resmodel\UserRoleTable;
use Resmodel\UserTable;
use Resmodel\TagTable;
use Resmodel\ArticleTagTable;

use Zend\Db\Adapter\Adapter;
use Zend\Db\ResultSet\ResultSet;

use Zend\Db\TableGateway\Feature\FeatureSet;

use Zend\Db\TableGateway\TableGateway;

/**
 * Class TableGatewayFactory
 * @package Model\Factory
 * @description use the class in case of cannot get service locator because the class do not follow DI principle
 */

class ResTableGatewayFactory{

    private static $_domain;

    /**
     * @var string
     */

    private static $_lang;

    /**
     * @param string $lang
     */
    public static function setLang($lang)
    {
        self::$_lang = $lang;
    }

    /**
     * @return string
     */
    public static function getLang()
    {
        return self::$_lang;
    }



    /**
     * @param mixed $domain
     *
     */
    public static function setDomain($domain)
    {
        self::$_domain = $domain;
    }

    /**
     * @return mixed
     */
    public static function getDomain()
    {
        return self::$_domain;
    }


    /**
     * @var Adapter
     */
    private static  $_defaultDbAdapter;


    /**
     * @return Adapter
     */
    public static function getDefaultAdapter(){
        if(!self::$_defaultDbAdapter){
            $modelModuleConfig = include MODULE_PATH.'/Model/config/module.config.php';
            self::$_defaultDbAdapter = new Adapter($modelModuleConfig['db']);
        }
        return self::$_defaultDbAdapter;
    }

    /**
     * @param \Zend\Db\Adapter\Adapter $defaultDbAdpter
     */
    public static function setDbAdapter($dbAdapter)
    {
        self::$_defaultDbAdapter = $dbAdapter;
    }


    public static function getDbAdapter()
    {
        if (!self::$_defaultDbAdapter)
            return self::getDefaultAdapter();
        else
            return self::$_defaultDbAdapter;
    }


    /**
     * @param $tableName
     * @param $entityClass
     * @return TableGateway
     */
    public static function getGenericTableGateway($tableName, $entityClass){
        $dbAdapter = self::getDbAdapter();
        $resultSetPrototype = new ResultSet();
        $resultSetPrototype->setArrayObjectPrototype($entityClass);

        $featureSet = new FeatureSet();
        $featureSet->addFeature(new LightMetaFeature());
        $featureSet->addFeature(new InjectMetaFieldFeature());
//        $featureSet->addFeature(new MetadataFeature());

        return new TableGateway($tableName, $dbAdapter, $featureSet, $resultSetPrototype);
    }

    /**
     * @return UserTable
     */
    public static function getUserTable(){
        $table = new UserTable();
        $table->setTableGateway(self::getGenericTableGateway('user', new User()));
        return $table;

    }

    /**
     * @return CountryTable
     */
    public static function getCountryTable(){
        $table = new CountryTable();
        $table->setTableGateway(self::getGenericTableGateway('country', new CountryTable()));
        return $table;

    }


    /**
     * @return BlockClassTable
     */
    public static function getBlockClassTable(){
        $table = new BlockClassTable();
        $table->setTableGateway(self::getGenericTableGateway('block_class', new BlockClass()));
        return $table;

    }

    /**
     * @return BlockInstanceTable
     */
    public static function getBlockInstanceTable(){
        $table = new BlockInstanceTable();
        $table->setTableGateway(self::getGenericTableGateway('block_instance', new BlockInstance()));
        return $table;
    }

    /**
     * @return TemplateTable
     */
    public static function getTemplateTable($lang){
        $table = new TemplateTable();
        $table->setTableGateway(self::getGenericTableGateway('template', new Template()));
        $table->setLang($lang);
        return $table;

    }

    /**
     * @return TemplateBlockTable
     */
    public static function getTemplateBlockTable(){
        $table = new TemplateBlockTable();
        $table->setTableGateway(self::getGenericTableGateway('template_block', new TemplateBlock()));

        return $table;

    }

    /**
     * @return PrivilegeTable
     */
    public static function getPrivilegeTable(){
        $table = new PrivilegeTable();
        $table->setTableGateway(self::getGenericTableGateway('privilege', new Privilege()));
        return $table;
    }

    /**
     * @return PrivilegeTypeTable
     */
    public static function getPrivilegeTypeTable(){
        $table = new PrivilegeTypeTable();
        $table->setTableGateway(self::getGenericTableGateway('privilege_type', new PrivilegeType()));
        return $table;
    }

    /**
     * @return RoleTable
     */
    public static function getRoleTable(){
        $table = new RoleTable();
        $table->setTableGateway(self::getGenericTableGateway('role', new Role()));
        return $table;
    }


    /**
     * @return RolePrivilegeTable
     */
    public static function getRolePrivilegeTable(){
        $table = new RolePrivilegeTable();
        $table->setTableGateway(self::getGenericTableGateway('role_privilege', new Role()));
        return $table;
    }


    /**
     * @return UserRoleTable
     */
    public static function getUserRoleTable(){
        $table = new UserRoleTable();
        $table->setTableGateway(self::getGenericTableGateway('user_role', new UserRole()));
        return $table;
    }

    /**
     * @return PageTable
     */
    public static function getPageTable(){
        $table = new PageTable();
        $table->setTableGateway(self::getGenericTableGateway('page', new Page()));
        return $table;
    }


    /**
     * @return PageBlockTable
     */
    public static function getPageBlockTable(){
        $table = new PageBlockTable();
        $table->setTableGateway(self::getGenericTableGateway('page_block', new PageBlock()));
        return $table;
    }

    /**
     * @return RouteTable
     */
    public static function getRouteTable($lang){
        $table = new RouteTable();
        $table->setTableGateway(self::getGenericTableGateway('route', new Route()));
        $table->setLang($lang);
        return $table;
    }

    /**
     * @return MenuTable
     */
    public static function getMenuTable($lang){
        $table = new MenuTable();
        $table->setTableGateway(self::getGenericTableGateway('menu', new Menu()));
        $table->setLang($lang);
        return $table;
    }

    /**
     * @return MenuItemTable
     */
    public static function getMenuItemTable(){
        $table = new MenuItemTable();
        $table->setTableGateway(self::getGenericTableGateway('menu_item', new MenuItem()));
        return $table;
    }

    /**
     * @var ArticleTable
     */
    private static $articleTable;

    /**
     * @return ArticleTable
     */
    public static function getArticleTable(){
        if(!self::$articleTable){
            $table = new ArticleTable();
            $table->setTableGateway(self::getGenericTableGateway('article', new Article()));
            $table->setDomain(self::getDomain());
            self::$articleTable = $table;
        }
        return self::$articleTable;
    }

    /**
     * @var ArticleCategoryTable
     */
    private static $articleCategoryTable;
    /**
     * @return ArticleCategoryTable
     */
    public static function getArticleCategoryTable(){
        if(!self::$articleCategoryTable){
            $table = new ArticleCategoryTable();
            $table->setTableGateway(self::getGenericTableGateway('article_category', new ArticleCategory()));
            $table->setDomain(self::getDomain());
            self::$articleCategoryTable = $table;
        }

        return self::$articleCategoryTable;

    }


    /**
     * @return ArticleTagTable
     */
    public static function getArticleTagTable(){
        $table = new ArticleTagTable();
        $table->setTableGateway(self::getGenericTableGateway('article_tag', new ArticleTag()));
        return $table;
    }

    /**
     * @return TagTable
     */
    public static function getTagTable($lang){
        $table = new TagTable();
        $table->setTableGateway(self::getGenericTableGateway('tag', new Tag()));
        $table->setLang($lang);
        return $table;
    }

    /**
     * @var CategoryTable
     */
    private static $categoryTable;
    /**
     * @return CategoryTable
     */
    public static function getCategoryTable(){
        if(!self::$categoryTable){
            $table = new CategoryTable();
            $table->setTableGateway(self::getGenericTableGateway('category', new Category()));
            $table->setLang(self::getLang());
            $table->setDomain(self::getDomain());
            self::$categoryTable = $table;
        }
        return self::$categoryTable;
    }

    /**
     * @var MlCategoryTable
     */
    private static $mlCategoryTable;
    /**
     * @return MlCategoryTable
     */
    public static function getMlCategoryTable(){
        if(!self::$mlCategoryTable){
            $table = new MlCategoryTable();
            $table->setTableGateway(self::getGenericTableGateway('ml_category', new MlCategory()));
            $table->setLang(self::getLang());
            $table->setDomain(self::getDomain());
            self::$mlCategoryTable = $table;
        }
        return self::$mlCategoryTable;
    }


    /**
     * @var MlCategoryLangTable
     */
    private static $mlCategoryLangTable;
    /**
     * @return MlCategoryLangTable
     */
    public static function getMlCategoryLangTable(){
        if(!self::$mlCategoryLangTable){
            $table = new MlCategoryLangTable();
            $table->setTableGateway(self::getGenericTableGateway('ml_category_lang', new MlCategoryLang()));
            $table->setLang(self::getLang());
            $table->setDomain(self::getDomain());
            self::$mlCategoryLangTable = $table;
        }
        return self::$mlCategoryLangTable;
    }


    /**
     * @param ResAbstractTable $table
     * @param string $domain
     */
  /*  private static  function injectAdapter($table){
        $table->setDomain(self::getDomain());
        $table->setAdapter(self::getDbAdapter());
    }*/


    /**
     * @var DishTable
     */
    private static $dishTable;
    /**
     * @return DishTable
     */
    public static function getDishTable(){
        if(!self::$dishTable){
            $table = new DishTable();
            $table->setTableGateway(self::getGenericTableGateway('dish', new Dish()));
            $table->setLang(self::getLang());
            $table->setDomain(self::getDomain());
            self::$dishTable = $table;
        }
        return self::$dishTable;

    }

    /**
     * @var DishLangTable
     */
    private static $dishLangTable;
    /**
     * @return DishLangTable
     */
    public static function getDishLangTable(){
        if(!self::$dishLangTable){
            $table = new DishLangTable();
            $table->setTableGateway(self::getGenericTableGateway('dish_lang', new DishLang()));
            $table->setDomain(self::getDomain());
            $table->setLang(self::getLang());
            self::$dishLangTable = $table;
        }

        return self::$dishLangTable;
    }

    /**
     * @var DishCategoryTable
     */
    private static $dishCategoryTable;
    /**
     * @return DishCategoryTable
     */
    public static function getDishCategoryTable(){
        if(!self::$dishCategoryTable){
            $table = new DishCategoryTable();
            $table->setTableGateway(self::getGenericTableGateway('dish_category', new DishCategory()));
            $table->setDomain(self::getDomain());
            self::$dishCategoryTable = $table;
        }
        return self::$dishCategoryTable;
    }

    /**
     * @var UnitTable
     */
    private static $unitTable;
    /**
     * @return UnitTable
     */
    public static function getUnitTable(){
        if(!self::$unitTable){
            $table = new UnitTable();
            $table->setTableGateway(self::getGenericTableGateway('unit', new Unit()));
            $table->setLang(self::getLang());
            $table->setDomain(self::getDomain());
            self::$unitTable = $table;
        }
        return self::$unitTable;
    }

    /**
     * @var UnitLangTable
     */
    private static $unitLangTable;
    /**
     * @return UnitLangTable
     */
    public static function getUnitLangTable(){
        if(!self::$unitLangTable){
            $table = new UnitLangTable();
            $table->setTableGateway(self::getGenericTableGateway('unit_lang', new UnitLang()));
            $table->setDomain(self::getDomain());
            self::$unitLangTable = $table;
        }

        return self::$unitLangTable;
    }

    /**
     * @var DishTagTable
     */
    private static $dishTagTable;
    /**
     * @return DishTagTable
     */
    public static function getDishTagTable(){
        if(!self::$dishTagTable){
            $table = new DishTagTable();
            $table->setTableGateway(self::getGenericTableGateway('dish_tag', new DishTag()));
            $table->setLang(self::getLang());
            $table->setDomain(self::getDomain());
            self::$dishTagTable = $table;
        }

        return self::$dishTagTable;
    }

    /**
     * @var DishPriceTable
     */
    private static $dishPriceTable;
    /**
     * @return DishPriceTable
     */
    public static function getDishPriceTable(){
        if(!self::$dishPriceTable){
            $table = new DishPriceTable();
            $table->setTableGateway(self::getGenericTableGateway('dish_price', new DishPrice()));
            $table->setDomain(self::getDomain());
            self::$dishPriceTable = $table;
        }
        return self::$dishPriceTable;
    }

    /**
     * @var DishArticleTable
     */
    private static $dishArticleTable;
    /**
     * @return DishArticleTable
     */
    public static function getDishArticleTable(){
        if(!self::$dishArticleTable){
            $table = new DishArticleTable();
            $table->setTableGateway(self::getGenericTableGateway('dish_article', new DishArticle()));
            $table->setLang(self::getLang());
            $table->setDomain(self::getDomain());
            self::$dishPriceTable = $table;
        }

        return self::$dishArticleTable;
    }

    /**
     * @var DishImageTable
     */
    private static $dishImageTable;
    /**
     * @return DishImageTable
     */
    public static function getDishImageTable(){
        if(!self::$dishImageTable){
            $table = new DishImageTable();
            $table->setTableGateway(self::getGenericTableGateway('dish_image', new DishImage()));
            $table->setDomain(self::getDomain());
            self::$dishImageTable = $table;
        }

        return self::$dishImageTable;
    }


    /**
     * @var DayDishTable
     */
    private static $dayDishTable;
    /**
     * @return DayDishTable
     */
    public static function getDayDishTable(){
        if(!self::$dayDishTable){
            $table = new DayDishTable();
            $table->setTableGateway(self::getGenericTableGateway('day_dish', new DayDish()));
            $table->setDomain(self::getDomain());
            self::$dayDishTable = $table;
        }

        return self::$dayDishTable;
    }













}

